﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Marbles.Core.Handlers;
using Marbles.Core.Content.Sites;
using System.Web;
using Marbles.Core.Content.Pages;
using Marbles.Core.Content.Syndication;
using Marbles.Core.Content.SiteMap;

namespace Marbles.Core.Handlers
{
    public class RSSFeed : IHttpHandlerBase
    {

        public List<IFeedItem> Items
        {
            get { return _items; }
            set { _items = value; }
        }

        public static string ContentType { get { return "application/rss+xml"; } }
        public bool IsReusable
        {
            get { return false; }
        }

        private List<IFeedItem> _items = null;

        public RSSFeed()
            : base()
        {
            _items = new List<IFeedItem>();
        }

        public RSSFeed(List<IFeedItem> items)
            : base()
        {
            _items = items;
        }

        public void ProcessRequest(HttpContext context)
        {
            string PageName = "Default";
            if (Marbles.Core.Settings.SettingsManager.TrustLevel == AspNetHostingPermissionLevel.Medium)
            {
                if (context.Request.Params["id"] != null) { PageName = context.Request.Params["id"].Trim().ToLower(); }
            }
            else { PageName = (context.Items["Name"] == null ? "Default" : context.Items["Name"].ToString()); }
            

            SiteDefinition site = SiteDefinition.GetCurrent();
            PageDefinition page = new PageDefinition(site.SiteName, PageName);
            context.Response.ContentType = "application/rss+xml";

            WebSiteMap map = new WebSiteMap(page, true);
            GetFeedItems(map, _items);
            
            Render(context.Response, page, site, _items);
            context.Response.Flush();
            context.Response.End();
        }

        private void GetFeedItems(WebSiteMap map, List<IFeedItem> items)
        {
            foreach (WebSiteMapNode node in map)
            {
                FeedItem item = new FeedItem();
                item.Title = node.Title;
                item.Description = node.Description;
                item.PublishDate = node.PublishDate;
                item.Link = node.Url;
                items.Add(item);
                if (node.HasChildren) { GetFeedItems(map, items); }
            }
        }

        public void Render(HttpResponse writer, PageDefinition Page, SiteDefinition Web, List<IFeedItem> Items)
        {
            writer.Write("<?xml version=\"1.0\"?>");
            writer.Write("<rss version=\"2.0\">");
            writer.Write("<channel>");
            writer.Write("<Generator></Generator>");
            writer.Write(string.Format("<title>{0}</title>", HttpUtility.HtmlEncode(Web.Title)));
            writer.Write(string.Format("<link>{0}</link>", HttpUtility.HtmlEncode(Page.Link)));
            writer.Write(string.Format("<description>{0}</description>", HttpUtility.HtmlEncode(Page.Title)));
            writer.Write(string.Format("<webMaster>{0}</webMaster>", HttpUtility.HtmlEncode(Web.WebMaster)));
            writer.Write(string.Format("<managingEditor>{0}</managingEditor>", HttpUtility.HtmlEncode(Page.ManagingEditor)));
            writer.Write(string.Format("<lastBuildDate>{0}</lastBuildDate>", Page.PublishDate.ToString("r")));
            writer.Write(string.Format("<copyright>{0}</copyright>", HttpUtility.HtmlEncode(Web.CopyRight)));
            writer.Write(string.Format("<pubDate>{0}</pubDate>", Page.PublishDate.ToString("r")));
            writer.Write(string.Format("<ttl>{0}</ttl>", 0));

            foreach (IFeedItem item in Items)
            {
                writer.Write(item.ToString());
            }

            writer.Write("</channel></rss>");
        }

        public string Verbs
        {
            get { return "GET"; }
        }

        public bool Validate
        {
            get { return false; }
        }

        public string Path
        {
            get { return "*.rss"; }
        }

        public string Name
        {
            get { return this.GetType().Name; }
        }
    }
}